package components.ship;

import com.uqbar.vainilla.DeltaState;
import com.uqbar.vainilla.appearances.Sprite;
import com.uqbar.vainilla.events.constants.Key;
import components.AsteroidCollComponent;
import components.weapon.Proyectile;

public abstract class Ship extends AsteroidCollComponent {

	private Sprite sprite;
	
	private double speed;
	private double turningSpeed;
	private double angle;
	private double dirVecX;
	private double dirVecY;
	private double maxSpeed;
	private double forwardAcel;
	private double deceleration;

	private ShipState state;
	


	public Ship(int aSpeed, int maxSpeed, int fAcell, int turningSpd,  int decel, int aDiameter, int aHeight, double x, double y, Sprite sp) {
		super(20, 20, x, y);
		this.speed = aSpeed;
		this.angle = 90;
		this.dirVecX = 0;
		this.dirVecY = 1;
		this.maxSpeed = maxSpeed;
		this.setForwardAcel(fAcell);
		this.turningSpeed = turningSpd;
		this.deceleration = decel;
		this.setSprite(sp);
		this.setAppearance(sp);
		this.state = new ShipRespawning(this);
	}

	@Override
	public boolean isSolid() {
		return false;
	}

	@Override
	protected void onCollisionWithSolid(AsteroidCollComponent gc) {
		
	}

	@Override
	protected void defineCollide(AsteroidCollComponent gc) {
		gc.collideWithShip(this);
	}

	@Override
	protected void effectiveUpdate(DeltaState deltaState) {

		double turning = this.turningSpeed * deltaState.getDelta();
		
		if (deltaState.isKeyBeingHold(Key.W)){
			double acell = this.getForwardAcel()* deltaState.getDelta();
			if (!(this.speed + acell > this.maxSpeed)){
				this.speed = this.speed + acell;
			}
		}
		else{
			double delta = this.deceleration * deltaState.getDelta();
			this.decelerate(delta);
		}
		if (deltaState.isKeyBeingHold(Key.A)){
			this.updateDir(-turning);
		}
		if (deltaState.isKeyBeingHold(Key.D)){
			this.updateDir(turning);
		}		
		
		if (deltaState.isKeyPressed(Key.SPACE)){
			this.shootMainWeapon();
		}
		
		this.getState().protectionTime(deltaState.getDelta());
		this.generciMove(deltaState, this.getSpeed(), this.getDirVecX(), this.getDirVecY());
	}

	private void decelerate(double delta) {
		if(this.speed - delta > 0){
			this.speed = this.speed - delta;
		}
	}

	protected void updateDir(double turning){
		this.angle = this.angle + turning;
		this.dirVecX = Math.cos(Math.toRadians(this.angle));
		this.dirVecY = Math.sin(Math.toRadians(this.angle));
		
		//this.sprite = Images.images.getImage("ship").rotate(Math.toRadians(this.angle - 90));
		this.setAppearance(this.getState().getShipAppearance());
	}

	public double getAngle() {
		return angle;
	}

	public void setAngle(double angle) {
		this.angle = angle;
	}

	protected void shoot(Proyectile proyectile){
		this.getScene().doShoot(proyectile);
	}
	

	protected void shootMainWeapon(){
		Proyectile p = this.getMainProyectile();
		p.setX(this.getX() + this.getDiameter()/2);
		p.setY(this.getY() + this.getHeight()/2);
		p.setDirVecX(this.getDirVecX());
		p.setDirVecY(this.getDirVecY());
		p.setSpeed(p.getSpeed() + this.getSpeed());
		
		this.shoot(p);
	}
	
	protected abstract Proyectile getMainProyectile();
	/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
	
	
	public double getSpeed() {
		return speed;
	}

	public void setSpeed(double speed) {
		this.speed = speed;
	}

	public double getTurningSpeed() {
		return turningSpeed;
	}

	public void setTurningSpeed(double turningSpeed) {
		this.turningSpeed = turningSpeed;
	}

	public double getDirVecX() {
		return dirVecX;
	}

	public void setDirVecX(double dirVecX) {
		this.dirVecX = dirVecX;
	}

	public double getDirVecY() {
		return dirVecY;
	}

	public void setDirVecY(double dirVecY) {
		this.dirVecY = dirVecY;
	}

	public double getMaxSpeed() {
		return maxSpeed;
	}

	public void setMaxSpeed(double maxSpeed) {
		this.maxSpeed = maxSpeed;
	}

	public double getDeceleration() {
		return deceleration;
	}

	public void setDeceleration(double deceleration) {
		this.deceleration = deceleration;
	}


	public double getForwardAcel() {
		return forwardAcel;
	}

	public void setForwardAcel(double forwardAcel) {
		this.forwardAcel = forwardAcel;
	}
	public ShipState getState() {
		return state;
	}

	public void setState(ShipState state) {
		this.state = state;
	}

	public void shipDestroyed() {
		if (this.isEnable()){
			this.setEnable(false);
			this.getScene().shipDestroyed(this);
		}
	}

	public Sprite getSprite() {
		return sprite;
	}

	public void setSprite(Sprite sprite) {
		this.sprite = sprite;
	}

}
